﻿#region Using directives

using System;
using System.Collections.Generic;
using System.Text;

#endregion
using System.IO;

namespace MindFactorial.Library
{
    public class BinaryFile
    {
        string internalbits;
        binary[] byteBits;
        long position = 0;

        /// <summary>
        /// Encapsulates a binary file for reading.  The benefit is that bits are exposed.
        /// Will allow for reading of unaligned bits but still realign itself when you attempt to read
        /// byte aligned data
        /// </summary>
        /// <param name="filename"></param>
        public BinaryFile(string filename)
        {
            FileStream fs = new FileStream(filename, FileMode.Open);
            byte[] buffer = new byte[fs.Length];
            fs.Read(buffer, 0, buffer.Length);
            fs.Close();

            //this snippet will take each byte in the file
            //convert it to a binary,
            //and combine the Bibaryies to produce a strin grepresentation
            //of all the bits in the file
            Queue<binary> bin = new Queue<binary>();
            StringBuilder tbits = new StringBuilder();
            foreach (byte b in buffer)
            {
                binary bits = b;
                bin.Enqueue(bits);
                tbits.Append(bits.ToString());
            }
            byteBits = bin.ToArray();
            internalbits = tbits.ToString();

        }

        public binary ReadBits(int length)
        {            
            string temp = internalbits.Substring((int)position, length);
            position += length;
            return new binary(temp);
        }

        binary ReadBits(int startposition, int length)
        {
            string temp = internalbits.Substring(startposition, length);            
            return new binary(temp);
        }

        public binary ReadBits(Alignment alignment)
        {
            //if not byte aligned, move until next byte alignment
            while (position % 8 != 0)
            {
                position++;
            }

            int length = (int)alignment;
            Queue<binary> bits = new Queue<binary>();
            for (int i = 8; i <= length ; i+=8)
            {
                //the equation below should always produce the current position as the start index
                //since i is inremented by 8 each iteration through;
                binary b = ReadBits((int)position + length - i, 8);
                bits.Enqueue(b);
            }

            binary retval = bits.Dequeue();
            foreach (binary b in bits)
            {
                retval.Combine(b);
            }
            position += length;
            return retval;
        }

    }
}
